﻿using BJoin.Application.BObject;
using BJoin.Application.Dto;
using BJoin.Application.Entity;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace BJoin.Application.IManager
{
    /// <summary>
    /// POCO Contract
    /// </summary>
    /// <typeparam name="TDto"></typeparam>
    /// <typeparam name="TEntity"></typeparam>
    /// <typeparam name="TKey"></typeparam>
    /// <typeparam name="TExt"></typeparam>
    public interface IPocoManager<TDto, TEntity, TKey,TExt> 
        where TDto : ResDto<TKey,TExt> where TEntity : Entity<TKey, TExt> where TExt:BObjExt
    {
        #region Common Async
        /// <summary>
        /// 获取总数
        /// </summary>
        /// <param name="filterDto">筛选实体</param>
        /// <returns>long</returns>
        Task<long> CountAsync<TFilterDto>(TFilterDto filter) where TFilterDto : ReqFilterDto<TKey,TExt>;
        /// <summary>
        /// 获取总数
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns>long</returns>
        Task<long> CountAsync(Expression<Func<TEntity,bool>> expression);
        /// <summary>
        /// 单条查询
        /// </summary>
        /// <param name="id">id</param>
        /// <returns>返回实体</returns>
        Task<TDto> GetSingleAsync(TKey id);
        /// <summary>
        /// 单条查询
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="funcConverter">转换器</param>
        /// <returns>动态对象</returns>
        Task<TDto> GetSingleAsync(TKey id, Action<TDto> actTranslater);
        /// <summary>
        /// 记录筛选
        /// </summary>
        /// <param name="filter">筛选实体</param>
        /// <param name="orderBy">排序</param>
        /// <returns>实体集合</returns> 
        Task<IEnumerable<TDto>> FilterAsync<TFilterDto>(TFilterDto filter, string[] orderBy = null) where TFilterDto : ReqFilterDto<TKey,TExt>;
        /// <summary>
        /// 记录筛选
        /// </summary>
        /// <param name="filter">筛选实体</param>
        /// <param name="funcConverter">转换器</param>
        /// <param name="orderBy">排序</param>
        /// <returns>实体集合</returns>        
        Task<IEnumerable<TDto>> FilterAsync<TFilterDto>(TFilterDto filter, Action<List<TDto>> actTranslater, string[] orderBy = null) where TFilterDto : ReqFilterDto<TKey,TExt>;

        /// <summary>
        /// 分批记录筛选
        /// </summary>
        /// <param name="filterDto">筛选实体</param>
        /// <param name="firstResult">第几条</param>
        /// <param name="maxResults">最大记录数</param>
        /// <returns>分页实体集合</returns>
        Task<IEnumerable<TDto>> LimitFilterAsync<TFilterDto>(TFilterDto filter, int firstResult, int maxResults, string[] orderBy = null) where TFilterDto : ReqFilterDto<TKey,TExt>;
        /// <summary>
        /// 分批记录筛选
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <param name="firstResult">第几条</param>
        /// <param name="maxResults">最大记录数</param>
        /// <returns>分页实体集合</returns>
        Task<IEnumerable<TDto>> LimitFilterAsync(Expression<Func<TEntity, bool>> expression, int firstResult, int maxResults, string[] orderBy = null);

        /// <summary>
        /// 分页记录筛选
        /// </summary>
        /// <param name="pageIndex">第几页</param>
        /// <param name="pageSize">每页数目</param>
        /// <param name="filterDto">筛选实体</param>
        /// <param name="orderBy">排序</param>
        /// <returns>分页实体集合</returns>
        Task<ResPagingDto<TDto>> PagingFilterAsync<TFilterDto>(TFilterDto filter, int pageIndex, int pageSize, string[] orderBy=null) where TFilterDto : ReqFilterDto<TKey,TExt>;
        /// <summary>
        /// 分页记录筛选
        /// </summary>
        /// <param name="pageIndex">第几页</param>
        /// <param name="pageSize">每页数目</param>
        /// <param name="expression">表达式</param>
        /// <param name="orderBy">排序</param>
        /// <returns>分页实体集合</returns>
        Task<ResPagingDto<TDto>> PagingFilterAsync(Expression<Func<TEntity, bool>> expression, int pageIndex, int pageSize, string[] orderBy=null);
        /// <summary>
        /// 单条新增
        /// </summary>
        /// <param name="dto">新增实体</param>
        /// <returns>id</returns>
        Task<TKey> AddAsync<TAddDto>(TAddDto addDto) where TAddDto : ReqAddDto<TExt>;
        /// <summary>
        /// 批量新增(小批量，超过100条需开启事务)
        /// </summary>
        /// <param name="addDtos">新增实体集合</param>
        /// <returns>true/false</returns>
        Task<IEnumerable<TKey>> AddManyAsync<TAddDto>(IEnumerable<TAddDto> addDtos) where TAddDto : ReqAddDto<TExt>;

        /// <summary>
        /// 更新(支持单一或多个属性)
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="dto">更新实体</param>
        /// <returns>true/false</returns>
        Task<bool> UpdateSetAsync<TUpdateDto>(TKey id, TUpdateDto updateDto) where TUpdateDto:ReqUpdateDto<TExt>;
        /// <summary>
        /// 更新（全部属性，支持Null）
        /// </summary>
        /// <param name="id">id</param>
        /// <param name="dto">更新实体</param>
        /// <returns>true/false</returns>
        Task<bool> UpdateAsync<TUpdateDto>(TKey id, TUpdateDto updateDto) where TUpdateDto : ReqUpdateDto<TExt>;
        /// <summary>
        /// ID单条删除
        /// </summary>
        /// <param name="id">id</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync(TKey id);
        /// <summary>
        /// 条件删除
        /// </summary>
        /// <param name="id">id</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync<TFilterDto>(TFilterDto filter) where TFilterDto : ReqFilterDto<TKey,TExt>;
        /// <summary>
        /// 条件删除
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> expression);
        /// <summary>
        /// []批量删除
        /// </summary>
        /// <param name="ids">ids,逗号分隔</param>
        /// <returns>true/false</returns>
        Task<bool> DeleteManyAsync(string ids);
        #endregion
    }
}
